perm filename PUZZLE.LSP[F87,JMC] blob
sn#850848 filedate 1987-12-27 generic text, type T, neo UTF8
;;; -*- Syntax: Common-lisp; Package: PZ -*-
;(defun bf (u good bad)
; (cond
; ((null u) (error "lose"))
; ((good (car u)) (car u))
; ((bad (car u)) (bf (cdr u) good bad))
; (t (bf (merge (cdr u) (succ (car u))) good bad))))
;(defun improve (p)
; (bf (succ p) #'(lambda (p1) (better p1 p))
; #'(lambda (p1) (worse p1 p))))
;;; (adjoin x u) adjoins the element x to the list u,
;;; and (merge u v) merges the lists u and v.
(def-worse-heuristic dont-break-chain (newboard oldboard)
(unless (zerop (board-completed-chain oldboard)) ; No chain to break.
(let* ((lefttile (leftsquare (board-completed-chain oldboard) oldboard))
(righttile (board-completed-chain oldboard)))
(dont-break-chain-1 lefttile righttile newboard))))
;(def-worse-heuristic dont-break-chain (newboard oldboard)
; (unless (zerop (board-completed-chain oldboard)) ; No chain to break.
; (let* ((lefttile (leftsquare (board-completed-chain oldboard) oldboard))
; (righttile (board-completed-chain oldboard)))
; (loop for tilenumber from lefttile below righttile
; when (not (contiguous tilenumber
; (1+ tilenumber) newboard))
; return t))))
(defun dont-break-chain-1 (m n board)
(if (= m n)
nil
(if (contiguous-1 m (1+ m) board)
(dont-break-chain-1 (1+ m) n board)
(if (contiguous m (1+ m) board)
(dont-break-chain-2 (1+ m) n board)
t))))
(defun dont-break-chain-2 (m n board)
(if (= m n)
nil
(if (contiguous-1 m (1+ m) board)
(dont-break-chain-2 (1+ m) n board)
t)))
(defun contiguous (tile1 tile2 board)
(let ((p1 (current-position tile1 board))
(p2 (current-position tile2 board)))
(or (and (= (row p1 board)(row p2 board))
(= (abs (- (column p1 board)(column p2 board))) 1))
(and (= (column p1 board)(column p2 board))
(= (abs (- (row p1 board)(row p2 board))) 1))
(and (not (or (eq tile1 :blank)(eq tile2 :blank)))
(contiguous tile1 :blank board)
(contiguous tile2 :blank board)))))
;;; contiguous without allowing intervening blanks
(defun contiguous-1 (tile1 tile2 board)
(let ((p1 (current-position tile1 board))
(p2 (current-position tile2 board)))
(or (and (= (row p1 board)(row p2 board))
(= (abs (- (column p1 board)(column p2 board))) 1))
(and (= (column p1 board)(column p2 board))
(= (abs (- (row p1 board)(row p2 board))) 1)))))
(defun whither-next (tile location board)
)
(def-better-heuristic Manhattan-distance (newboard oldboard)
(let* ((nexttile (1+ (board-completed-chain oldboard)))
(currentpos (current-position nexttile oldboard)))
(unless (equal (position-contents currentpos newboard) ; If the tile hasn't changed position,
nexttile) ; don't calc the manhattan distance.
(and
(> (man-dist nexttile currentpos (board-side oldboard))
(man-dist nexttile (current-position nexttile newboard)
(board-side oldboard))) ; The final = test checks to prohibit undoing
(>= (completed-chain newboard) nexttile))) ; the existing complete chain.
))